package org.ihelpuoo.weboo.module;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.ihelpuoo.io.FileUtils;
import org.ihelpuoo.localize.LocaleComparator;
import org.ihelpuoo.util.EscapeableProperties;
import org.ihelpuoo.util.Properties;
import org.ihelpuoo.weboo.Messager;
import org.ihelpuoo.weboo.Weboo;

public class WebooMessager implements Messager
{
	private Map<String, Properties>	msgs;
	private String					fileName;
	private List<Locale>			installedLocales;

	public WebooMessager(String fileName)
	{
		this.fileName = fileName;
		msgs = new HashMap<String, Properties>();
		installedLocales = new LinkedList<Locale>();
	}

	public String getMessageFileName()
	{
		return fileName;
	}

	public String getMessage(Locale locale, String key)
	{
		String msg = null;
		Properties msgset = get(locale);
		if (null == msgset)
			return null;
		msg = msgset.getString(key);
		return msg;
	}

	private boolean loadLocaleMessageFile(Locale locale, boolean isEscaped)
	{
		if (null == locale)
		{
			if (msgs.containsKey(null))
				return true;
			try
			{
				File f = FileUtils.findFile(fileName);
				if (null != f && f.exists())
				{

					Properties p = new EscapeableProperties(new BufferedInputStream(
							new FileInputStream(f)),isEscaped,Weboo.MESSAGE_ENCODING);
					msgs.put(null,p);
				}
				else
					return false;
			}
			catch (Exception e)
			{
				return false;
			}
		}
		else
		{
			if (msgs.containsKey(locale.toString()))
				return true;
			try
			{
				File f = FileUtils.findFile(FileUtils.addSuffixInFileName(fileName,"_"
						+ locale.toString()));
				if (null != f && f.exists())
				{
					Properties p = new EscapeableProperties(new BufferedInputStream(
							new FileInputStream(f)),isEscaped);
					msgs.put(locale.toString(),p);
				}
				else
					return false;
			}
			catch (Exception e)
			{
				return false;
			}
		}
		return true;
	}

	public Properties get(Locale locale)
	{
		if (null == locale)
			return msgs.get(null);
		Properties p = msgs.get(locale.toString());
		if (null == p)
		{
			p = (Properties)msgs.get((new StringBuffer(locale.getLanguage())).append('_').append(
					locale.getCountry()));
			if (null == p)
			{
				p = (Properties)msgs.get(locale.getLanguage());
				if (null == p)
					p = (Properties)msgs.get(null);
			}

		}
		return p;
	}

	void initLocales(boolean isEscaped)
	{
		if (loadLocaleMessageFile(null,isEscaped))
			installedLocales.add(null);
		Locale[] locales = Locale.getAvailableLocales();
		for (int i = 0; i < locales.length; i++)
			if (loadLocaleMessageFile(locales[i],isEscaped))
				installedLocales.add(locales[i]);
		Collections.sort(installedLocales,LocaleComparator.me());
	}

	public List<Locale> getLocales()
	{
		return installedLocales;
	}

	public Set<String> keys(Locale locale)
	{
		Properties p = get(locale);
		if (null == p)
			return null;
		return p.keySet();
	}

	public Collection<String> values(Locale locale)
	{
		Properties p = get(locale);
		if (null == p)
			return null;
		return p.values();
	}

}
